/*
 * @Author: yanfeng@sailvan.com
 * @Date: 2023-07-17 09:39:41
 * @LastEditors: zhengguiyong zhengguiyong@sailvan.com
 * @LastEditTime: 2023-08-02 18:35:13
 * @FilePath: /tbox_meige/src/adapt/adapt.c
 * @Description: 适配层-对其他模块进行封装供主线程调用,减少模块间依赖
 * @coded forma: UTF-8
 * Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
 */

#include  "stdio.h"
#include  "stdlib.h"
#include  "string.h"
#include  <time.h>
#include "fw_interface.h"
#include "bsp.h"
#include "task_gnss.h"
#include "gnss_public.h"
#include "gnss_power_mgr.h"
#include "service/include/swei_alarm.h"
#include "service/include/swei_active.h"
#include "misc/misc_api.h"
#include "misc/misc_system.h"

#include "elog.h"
#include "gsensor/gsensor.h"

#include "adapt.h"
#include "../gsensor/fw_interface.h"
#include "../drivers/sensor/sensor_support.h"
#include "../drivers/sensor/skeleton/sensor_support_chip.h"
#include "../drivers/sensor/icm42670/icm42670.h"
#include "../drivers/sensor/icm42670/sensor_icm42670.h"


extern gnss_task_manage_t *gnss_task_manage;


int fw_gsensor_check(void)
{
    icm42670_sensor_initialize();
    
    return 0;
}


/*gsensor measure range : 2--2G;  4--4G  ;  8--8G;  16--16G*/
int fw_gsensor_set_measure_range(int nRange)   /* nRange  only 2  ,4   , 8  ,16 */
{
	return  icm42670_accel_range_set(nRange);
}


int fw_gsensor_set_sampled_frequency(int frequency) //frequency  100, 200, 400;
{
    return icm42670_odr_set(frequency);
}


/* 获取传感器三轴加速度和温度适配接口 */
int fw_gsensor_get_info(struct FW_GSENSOR_INFO_STRU *info)
{
    if (NULL == info)
		return FAILURE;

    struct acceleration accel = {0};
	if ( 0 == icm42670_sensor_accel_frame_get(&accel)) {
		info->acc_x = accel.x * 1.0f / sensor_accel_1g_range_count();
		info->acc_y = accel.y * 1.0f / sensor_accel_1g_range_count();
	    info->acc_z = accel.z * 1.0f / sensor_accel_1g_range_count();

        /* 震动告警判断缓存 */
        unsigned int max_count = accel_src_buffer_max_count();
        accel_src_t* accel_src_buffer = accel_src_buffer_get();
        unsigned int accel_index = accel_src_buffer_wr_index_get();
        accel_src_buffer[accel_index].x = accel.x;
        accel_src_buffer[accel_index].y = accel.y;
        accel_src_buffer[accel_index].z = accel.z;

        if (++accel_index >= max_count) {
            accel_src_buffer_wr_index_set(0);
        } else {
            accel_src_buffer_wr_index_set(accel_index);
		}
		
	} else 
		return FAILURE;
		
    info->temp = icm42670_sensor_temperature_get(); 
#if 0
	log_i("acc_raw: acc_x:%d, acc_y:%d, acc_z:%d, temp:%.1f.\r\n", \
			accel.x, accel.y, accel.z, info->temp);
#endif
	return SUCCESS;
}


/* 获取传感器三轴角速度适配接口 */
int fw_gyroscope_get_info(struct FW_GYROSCOPE_INFO_STRU *info)
{
    if (NULL == info)
		return FAILURE;

    struct angularrate gyro = {0};
	if ( 0 == icm42670_sensor_gyro_frame_get(&gyro)) {
		info->gyro_x = gyro.x * 1.0f / sensor_gyro_1dge_per_s_range_count();
		info->gyro_y = gyro.y * 1.0f / sensor_gyro_1dge_per_s_range_count();
	    info->gyro_z = gyro.z * 1.0f / sensor_gyro_1dge_per_s_range_count();

		/*单位转换: 度/S转为弧度/S */
		info->gyro_x = info->gyro_x * 3.1415926f / 180;
		info->gyro_y = info->gyro_y * 3.1415926f / 180;
		info->gyro_z = info->gyro_z * 3.1415926f / 180;
		
	} else 
		return FAILURE;
#if 0
	log_i("gyro_raw: gyro_x:%d, gyro_y:%d, gyro_z:%d.\r\n", \
			gyro.x, gyro.y, gyro.z);
#endif
	return SUCCESS;

}


int fw_gsensor_set_threshold(int glevel) //0-2 255
{
    int sense_value;

    float sensor_adc_per_mg = get_gsensor_local_run_config()->measure_range*1000.0f/icm42670_sensor_max_accel_value();

    if ( (glevel >= SENSITIVITY_LOW_LEVEL) && (glevel <= SENSITIVITY_HIGH_LEVEL)) {
        sense_value = (int)((SENSITIVITY_HIGH_LEVEL - glevel + 1) * SENSITIVITY_PER_CLASS_VALUE * sensor_adc_per_mg);
    } else if(SENSITIVITY_VERY_HIGH_LEVEL == glevel){
        sense_value = (int)(SENSITIVITY_VERY_HIGH_VALUE * sensor_adc_per_mg);   //判断异动时LEVEL255极高灵敏度
    } else {
        sense_value = (int)(SENSITIVITY_PER_CLASS_VALUE * sensor_adc_per_mg);  //默认LEVEL0灵敏度
    }

    if (0 == icm42670_accel_sensitivity_set(sense_value)) {

        sensor_motion_on_accel_threshold_set(glevel);

        return SUCCESS;

    } else {
        return ERROR;
    }
    
}


/**
 * @description: 获取设备的时间戳
 * @return {*}
 * @Date: 2023-08-10 16:38:23
 * @modification: 
 */
int swei_get_dev_timestamp(void)
{
    return getsec();
}



/**
 * @description: 发送gsensor震动告警消息到服务器,低功耗模式下直接发送不需要从队列中取 
 * @param {void} *arg
 * @return {*}
 * @Date: 2023-9-28 09:00:00
 * @modification:
 */
int swei_netProtocol_send_gsensor_warning_msg(swei_alarm_id_e alarm_id)
{
    return swei_alarm_setup(alarm_id);
}


/* 原SWEI低功耗投票项，目前主要是Gsensor在应用 */
static char power_business_flag = 0;

char get_power_business_flag(void)
{
    return power_business_flag;
}

/***********************************************************************
 * 函数名称: tbox_power_set_business_flag
 * 作    者:   yanfeng 
 * 设计日期: 2023-08-08 11:02
 * 功能描述: 处理低功耗业务时设置各业务标志位
 * 参    数:  
 * 返 回 值: 
 * 修改日期:          修改人          修改内容
 ***********************************************************************/
int tbox_power_set_business_flag(char type, uint8_t value)
{
    if(value)
        power_business_flag |= (1 << type);
    else 
        power_business_flag &= ~(1 << type);

    return SUCCESS;
}



bool tbox_get_reboot_flag(void)
{
    return get_system_reboot_off_flag();
}



int tm_timetostr(struct tm *t, char *buf, int len) 
{
    return snprintf(buf, len, ",%04d-%02d-%02d %02d:%02d:%02d",
           t->tm_year,t->tm_mon,t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);    
 }


/*
目前应用需要：
info.latitude, info.longitude, info.satellites_num,info.utc_time

*/
int swei_gps_get_info(struct FW_GPS_INFO_STRU *info)
{
    if(NULL == info)
		return -1;
	
    //return fw_gps_get_info(info);
    struct fix_info gnss_info = {0};
	struct sat_info sat = {0};
	unsigned int sat_num = 0;
	

	get_last_gnss_info(&gnss_info);
	get_last_sat_info(&sat, &sat_num);

	//info->azimuth
	info->speed = gnss_info.speed;
	info->altitude = gnss_info.altitude;
	info->longitude = gnss_info.longitude;
	info->latitude = gnss_info.latitude;

	tm_timetostr(&(gnss_info.utc), info->utc_time, sizeof(info->utc_time));
	info->satellites_num = sat_num;

	info->status = (gnss_info.state == FIX_INVALID) ? GPS_ON_POSITIONING : GPS_IS_FIXED;
	

	return 0;
}


/*****************************************************************************
 * Function      : get_utctime_timestamp
 * Description   : 把utc时间转换成时间戳
 * Input         : void
 * Output        : None
 * Return        :
 * Others        :
 * Record
 * 1.Date        : 20230728
 *   Author      : yanfeng
 *   Modification: Created function

*****************************************************************************/
time_t get_utctime_timestamp(char time_arr[])
{
    struct tm tm;
    time_t timestamp;
    int year = 0;
    int mon = 0;
    int day = 0;

    // 解析时间字符串
    //strptime(time_arr, "%Y-%m-%d %H:%M:%S", &tm);
    sscanf(time_arr, "%d-%d-%d %d:%d:%d", &year, &mon, &day, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
    tm.tm_year = year - 1900;
    tm.tm_mon = mon - 1;
    tm.tm_mday = day;

    // 转换为时间戳
    timestamp = mktime(&tm);

    return timestamp;
}


int snsr_exit_lowpower = 0; /* 退出低功耗 */
int tbox_power_quit_sleep(void)
{
    return snsr_exit_lowpower;
}


int swei_get_sys_run_state(char type)
{
    return misc_get_active_state();
}



